<template>
  <div class="input-container">
    <div class="chat-input" contenteditable @mousedown="getLastLocation" @keydown="keydownFunc" @keyup="keyupFunc" @paste.prevent="pasteFunc" @input="inputFunc"></div>
  </div>
</template>

<script>
import { transToTag } from '@/utils/utils'

export default {
  name: 'chat-input',
  props: {
  },
  data () {
    return {
      content: '',
      // 光标最后的位置
      lastLocation: null,
    }
  },
  mounted () {
    this.chatInput = this.$el.querySelector('.chat-input')
    this.selection = getSelection()
  },
  methods: {
    // api
    // 插入表情
    addEmoji (index) {
      this.lastLocation || this.getLastLocation()

      let emoji = document.createElement('img')
      emoji.src = ''
      emoji.alt = `[emoji-${index}]`
      emoji.draggable = false;
      emoji.style = `
        height: 22px;
        width: 24px;
        background: url(${require("@/assets/emoji/emoji.png")});
        background-repeat: no-repeat;
        background-size: 24px;
        margin:0 1px;
        background-position:0 ${-24 * index}px;
        vertical-align: text-bottom;
      `
      this.insertNode(emoji)
    },

    // 发送消息
    sendMsg () {
      let content = this.chatInput.innerHTML.trim()
      if (content === '') {
        this.$message.warn('发送内容不能为空哦')
        return;
      }

      content = this.getAltValue(content)
      content = content.replace(/</gi, '&lt;').replace(/>/gi, '&gt;')

      this.$emit('sendMsg', content)
      this.chatInput.innerHTML = ''
    },

    // 事件回调
    // 粘贴事件
    pasteFunc (e) {
      // console.log(e.clipboardData.files[0]);
      let file = e.clipboardData.files[0]
      if (file) { this.$emit('uploadFile', file); return }

      // 去除样式
      let content = e.clipboardData.getData('text')
      // 转译标签，防止用户手动插入标签
      content = content.replace(/</gi, '&lt;').replace(/>/gi, '&gt;')

      content = transToTag(content)
      // 将文本插回光标处
      document.execCommand('insertHTML', false, content)
      this.inputFunc()
    },

    // 输入的回调
    inputFunc () {
      this.getLastLocation()

      // contenteditable末尾换行必须至少存在一个\n
      if (!/\n$/.test(this.chatInput.innerHTML)) {
        let node = document.createTextNode('\n')
        this.chatInput.appendChild(node)
      }
    },

    // 键盘按下的回调
    keydownFunc (e) {
      let kc = e.keyCode
      if (e.ctrlKey && kc === 13) {
        e.preventDefault()
        let node = document.createTextNode('\n')
        this.insertNode(node)
        this.chatInput.scrollTo({
          top: this.chatInput.scrollTop + 20,
          behavior: 'smooth'
        })
      } else if (kc === 13) {
        e.preventDefault()
        this.sendMsg()
      }
    },

    // 键盘弹起的回调
    keyupFunc (e) {
      let kc = e.keyCode
      if (kc >= 37 && kc <= 40) {
        this.getLastLocation()
      } else if (kc === 8) {
        // 退格在删完最后一行内容时会产生br
        if (/<br>/g.test(this.chatInput.innerHTML)) {
          this.chatInput.innerHTML = this.chatInput.innerHTML.replace(/<br>/g, '')
          let range = window.getSelection() // 创建range
          range.selectAllChildren(this.chatInput) // range 选择obj下所有子内容
          range.collapseToEnd() // 光标移至最后
        }
      }
    },

    // 方法
    // 记录光标的位置
    getLastLocation () {
      this.chatInput.focus()
      this.lastLocation = this.selection.getRangeAt(0)
      this.lastLocation.collapse(false)
    },

    // 插入节点
    insertNode (node) {
      this.selection.removeAllRanges()
      this.selection.addRange(this.lastLocation)

      this.lastLocation.deleteContents()
      this.lastLocation.insertNode(node)
      this.inputFunc()
    },

    // 获取img标签中alt的值
    getAltValue (content) {
      let reg = /<img.*?alt="(.*?)".*?>/g
      return content.replace(reg, '$1');
    },
  },
}
</script>

<style scoped>
.chat-input {
  height: 102px;
  text-align: left;
  white-space: pre-wrap;
  word-break: break-all;
  overflow-y: scroll;
  line-height: 20px;
  padding: 0 22px;
}

.chat-input:focus {
  outline: none;
}
</style>